# coding=utf-8
import click
import pathlib
from datetime import datetime, time, timedelta
from gm.api import *
from sys import platform
from quant import strategy
from quant.data import jisilu, utils
from quant.trader.juejin import JuejinTrader
from quant.vlogger import VLogger

start_date = '2022-04-07'


def init(context):
    VLogger.v = 1
    context.confirm = True
    cfg = strategy.ConbondStrategy.strategy_cfg(
        'multi_factors_rank', {
            'year': 1,  # 剩余年限
            'days_to_qualify_redeem': 5,
            'cpr_threshold': 1,  # 转股溢价率阈值
            'threshold': 130,  # 价格阈值
            'size': 6,  # 规模阈值（亿元）
            'rebalance': '日',  # 轮动周期
            'days_to_stop_trading': 10,  # 距离停止交易日阈值
            'days_from_listing': 10,  # 距离首次上市交易日阈值
            'weight_price': 0.1,  # 价格权重
            'weight_cpr': 0.8,  # 转股溢价率权重
            'weight_remaining_size': 0.1,  # 剩余规模权重
            'top': 20,  # 选取标的个数
        })
    data_dir = pathlib.Path(__file__).parent.parent.joinpath('data')

    if context.mode == MODE_LIVE:
        data_fn = lambda context, bar_dict: jisilu.refresh_now(
            data_dir.joinpath('jisilu'), to_juejin=True)[1]
    else:
        data_fn = utils.conbond_backtest_data_fn(start_date, data_dir)

    context.strategy = strategy.ConbondRotateStrategy(
        cfg, data_fn, JuejinTrader())
    context.strategy.init(context)
    if context.mode == MODE_LIVE and context.now.time() > time(9, 35, 0):
        context.strategy.rebalance(context)


def on_order_status(context, order):
    dt = context.now
    if order.status == OrderStatus_Filled:
        VLogger.vlog(
            2, '{}: {} order_book_id: {}, price: {}, volume: {}, value: {}'.
            format(dt, '买入' if order.side == OrderSide_Buy else '卖出',
                   order.symbol, order.price, order.volume, order.value))
    elif order.status == OrderStatus_Rejected:
        VLogger.error('{}: status: {}, target: {}, error: {}'.format(
            dt, order.status, order.symbol, order.ord_rej_reason_detail))
        if context.confirm:
            VLogger.error(order)
            VLogger.error(context.account().position(order.symbol,
                                                     PositionSide_Long))
            context.confirm = click.confirm('Error', default=True)
    else:
        VLogger.vlog(2, '{}: {}'.format(dt, order))


# 查看最终的回测结果
def on_backtest_finished(context, indicator):
    VLogger.vlog(0, indicator)
    VLogger.vlog(0, context.strategy.description)


if __name__ == '__main__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
    '''
    import logging
    logging.getLogger().setLevel(logging.INFO)
    run(strategy_id='334af32d-a5a8-11ec-b6e4-2a16a8610fe9',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='567120cd2f9b2ce8ae3fbd7ee76ed06bf899b512',
        backtest_start_time='%s 00:00:00' % start_date,
        backtest_end_time='%s 00:00:00' % (datetime.now().date() - timedelta(days=1)),
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=300000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)
